package utils

import (
	"bytes"
	"fmt"
	"log"
	"net/smtp"
	"text/template"

	"github.com/spf13/viper"
)

// MailConfig 邮件配置结构体
type MailConfig struct {
	SMTPHost     string `yaml:"smtp_host"`
	SMTPPort     int    `yaml:"smtp_port"`
	SMTPUsername string `yaml:"smtp_username"`
	SMTPPassword string `yaml:"smtp_password"`
	FromEmail    string `yaml:"from_email"`
}

// MailTemplate 邮件模板结构体
type MailTemplate struct {
	Subject string `yaml:"subject"`
	Body    string `yaml:"body"`
}

// MailSender 邮件发送器结构体
type MailSender struct {
	config   MailConfig
	template *template.Template
}

// NewMailSender 创建邮件发送器
func NewMailSender() (*MailSender, error) {
	// 从viper配置中读取邮件配置
	config := MailConfig{
		SMTPHost:     viper.GetString("mail.smtp_host"),
		SMTPPort:     viper.GetInt("mail.smtp_port"),
		SMTPUsername: viper.GetString("mail.smtp_username"),
		SMTPPassword: viper.GetString("mail.smtp_password"),
		FromEmail:    viper.GetString("mail.from_email"),
	}

	// 验证必要的配置项
	if config.SMTPHost == "" || config.SMTPUsername == "" || config.SMTPPassword == "" {
		return nil, fmt.Errorf(ErrParseConfig + ": missing required mail configuration")
	}

	return &MailSender{config: config}, nil
}

// LoadTemplate 加载邮件模板
func (ms *MailSender) LoadTemplate(templatePath string) error {
	tpl, err := template.ParseFiles(templatePath)
	if err != nil {
		return fmt.Errorf(ErrLoadTemplate+": %v", err)
	}
	ms.template = tpl
	return nil
}

// SendMail 发送邮件
func (ms *MailSender) SendMail(to []string, data interface{}) error {
	if ms.template == nil {
		return fmt.Errorf(ErrTemplateNotLoaded)
	}

	var body bytes.Buffer
	if err := ms.template.Execute(&body, data); err != nil {
		return fmt.Errorf(ErrRenderTemplate+": %v", err)
	}

	auth := smtp.PlainAuth("", ms.config.SMTPUsername, ms.config.SMTPPassword, ms.config.SMTPHost)
	msg := []byte(
		"To: " + to[0] + "\r\n" +
			"Subject: " + ms.template.Name() + "\r\n" +
			"\r\n" +
			body.String() + "\r\n")

	err := smtp.SendMail(
		fmt.Sprintf("%s:%d", ms.config.SMTPHost, ms.config.SMTPPort),
		auth,
		ms.config.FromEmail,
		to,
		msg,
	)

	if err != nil {
		return fmt.Errorf(ErrSendMail+": %v", err)
	}

	log.Printf("邮件发送成功: %s", to)
	return nil
}
